package com.scheduled.service.impl;

import com.scheduled.manager.ScheduledManager;
import com.scheduled.mapper.ScheduledMapper;
import com.scheduled.pojo.ScheduledRequest;
import com.scheduled.pojo.dto.BaseResponseDTO;
import com.scheduled.service.ScheduledService;
import com.scheduled.service.constant.ServiceConstant;
import com.scheduled.util.RestTemplateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 定时任务服务实现
 *
 * @author : z_sz
 * @date : 2020-08-10 10:24
 **/
@Service
public class ScheduledServiceImpl implements ScheduledService {

    /**
     * 延迟任务mapper层对象
     */
    @Autowired
    ScheduledMapper scheduledMapper;

    /**
     * 定时任务管理器
     */
    @Autowired
    ScheduledManager scheduledManager;

    /**
     * 服务端口号，为了模仿集群环境，通过服务端口号来区别服务
     */
    @Value("${server.port}")
    private String serverPort;

    @Override
    public String delayExecute(ScheduledRequest scheduledRequest) throws UnknownHostException {
        // 生成任务主键
        String id = UUID.randomUUID().toString().replace("-", "");
        scheduledRequest.setId(id)
                .setTaskStatus(0)
                .setTaskIp(InetAddress.getLocalHost()
                        .getHostAddress() + ":" + serverPort);
        scheduledMapper.insertScheduledTask(scheduledRequest);
        // 调用延迟执行方法
        Boolean delayResult = scheduledManager.delayExecute(() -> {
            System.out.println("任务执行，执行时间为："
                    + scheduledRequest.getExecuteTime() +
                    ",执行标题为：" + scheduledRequest.getExecuteTitle());
            // 修改任务的执行状态
            scheduledMapper.updateTaskStatus(id);
        }, scheduledRequest.getExecuteTime(), id);
        if (!delayResult) {
            return "任务设置失败";
        }
        return "任务设置成功";
    }

    @Override
    public BaseResponseDTO delayCancel(String id) throws UnknownHostException {
        ScheduledRequest scheduledRequest = scheduledMapper.getTask(id);
        if (Objects.isNull(scheduledRequest) && scheduledRequest.getTaskStatus() == 1) {
            return new BaseResponseDTO().setCode(-1).setMsg("该任务不存在或已执行");
        }
        String taskIp = scheduledRequest.getTaskIp();
        String serverIp = InetAddress.getLocalHost().getHostAddress() + ":" + serverPort;
        if (!serverIp.equals(taskIp)) {
            // 设置参数列表
            Map<String, String> map = new HashMap<>(3);
            map.put("id", id);
            // 如果任务所在的服务器不是当前服务器，则将请求转向任务所在的服务器
            BaseResponseDTO responseDTO = RestTemplateUtil.getForJson(taskIp + ServiceConstant.INTERFACE_PATH, map, BaseResponseDTO.class);
            if (Objects.nonNull(responseDTO)) {
                return responseDTO;
            }
            return new BaseResponseDTO().setCode(-1).setMsg("取消延迟任务失败");
        }
        // 任务所在服务器为当前服务器，直接执行取消方法
        boolean cancelResult = scheduledManager.cancelScheduled(id);
        if (!cancelResult) {
            return new BaseResponseDTO().setCode(-1).setMsg("取消延迟任务失败");
        }
        // 取消之后删除该任务信息
        scheduledMapper.deleteTask(id);
        return new BaseResponseDTO().setCode(0).setMsg("取消延迟任务成功");
    }
}
